﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;

namespace SmartText.Converter
{
    class XMLToDictionary
    {
        public static Dictionary<string, object> Parse(string xmlString)
        {
            return MakeDict(XDocument.Parse(xmlString).Root);
        }

        public static Dictionary<string, object> Load(string fileName)
        {
            return MakeDict(XDocument.Load(fileName).Root);
        }

        private static Dictionary<string, object> MakeDict(XElement xeRoot)
        {
            var ret = new Dictionary<string, object>();

            ret.Add(xeRoot.Name.LocalName, GetDictionaryFromXML(xeRoot));
            return ret;
        }

        private static object GetDictionaryFromXML(XElement xe)
        {
            var ret = new Dictionary<string, object>();

            foreach (var att in xe.Attributes())
            {
                ret.Add(att.Name.LocalName, ConvertValue(att.Value));
                //AddValue(ret, att.Name.LocalName, att.Value);
            }

            foreach (var element in xe.Elements())
            {
                if (ret.ContainsKey(element.Name.LocalName))
                {
                    continue;
                }

                if (xe.Elements(element.Name).Count() > 1)
                {
                    if (element.HasElements)
                    {
                        ret.Add(element.Name.LocalName,
                            xe.Elements(element.Name).Select(
                                n => GetDictionaryFromXML(n)
                            ).ToList());
                        continue;
                    }
                    else if (element.Value != null)
                    {
                        ret.Add(element.Name.LocalName,
                            xe.Elements(element.Name).Select(
                                n => ConvertValue(n.Value)
                            ).ToList());
                        continue;
                    }
                    
                }

                if (element.HasElements)
                {
                    ret.Add(element.Name.LocalName, GetDictionaryFromXML(element));
                }
                else
                {
                    //AddValue(ret, element.Name.LocalName, element.Value);
                    ret.Add(element.Name.LocalName, ConvertValue(element.Value));
                }
            }

            //if (!xe.HasElements && xe.Value != null)
            //{
            //    AddValue(ret, xe.Name.LocalName, xe.Value);
            //}
            return ret;
        }

        //private static void AddValue(Dictionary<string, object> dict, string key, string value)
        //{
        //    int iNum;
        //    double dNum;
        //    if (double.TryParse(value, out dNum))
        //    {
        //        dict.Add(key, dNum);
        //    }
        //    else if (int.TryParse(value, out iNum))
        //    {
        //        dict.Add(key, iNum);
        //    }
        //    else
        //    {
        //        dict.Add(key, value);
        //    }
        //}

        private static object ConvertValue(string value)
        {
            int iNum;
            double dNum;
            if (double.TryParse(value, out dNum))
            {
                return dNum;
            }
            else if (int.TryParse(value, out iNum))
            {
                return iNum;
            }
            else
            {
                return value;
            }
        }
    }
}
